package com.veer.shop.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Optional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.veer.shop.annotation.ApiSecured;
import com.veer.shop.config.Constants;
import com.veer.shop.config.ResponseCodeEnum;
import com.veer.shop.pojo.ResponseData;
import com.veer.shop.utils.JwtUtil;
import com.veer.shop.utils.ResponseUtil;

/**
 * 校验授权 拦截器
 * 
 * @author WangBin
 * 2020年8月12日-上午9:40:41
 */
public class AuthInterceptor implements HandlerInterceptor{
	
	private static final Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);
	
	@Autowired
	private JwtUtil jwtUtils;
	@Autowired
	ObjectMapper jackJsonMapper;
	
	/**
     * 在请求处理之前进行调用（Controller方法调用之前）
     */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		
		// 判断是否有注解
		boolean hasAnnotataion = handler.getClass().isAssignableFrom(HandlerMethod.class);
		
		if(!hasAnnotataion) {
			return true;
		}
			
		// 判断是否有 @UserApiSecured 注解
		ApiSecured apiSecured = ((HandlerMethod)handler).getMethodAnnotation(ApiSecured.class);
		
		if(apiSecured == null || !apiSecured.secured()) {
			return true;
		}
		
		Optional<String> token = null;
		
		try {
			// 获取 header 头中的 Authorization
			token = Optional.ofNullable(request.getHeader(Constants.HTTP_HEADER_AUTHORIZATION));
			logger.debug("获取的token：" + token.get());
		} catch (Exception e) {
			// 返回 token 无效或为空
			returnJson(response, ResponseUtil.error(ResponseCodeEnum.NO_TOKEN_ERROR));
		}

		if(token.isPresent() && !StringUtils.isEmpty(token.get())) {
			// 授权方式 ADMIN 或 CUSTOMER
			boolean isAdmin = apiSecured.isAdmin();
			if(isAdmin) {
				// 校验 Admin token
				if(jwtUtils.verifyAdminJwt(token.get())) {
					return true;
				}
			}

			// 校验 Customer Token
			if(jwtUtils.verifyCustomerJwt(token.get())) {
				return true;
			}
			
			// 返回 token 无效或为空
			returnJson(response, ResponseUtil.error(ResponseCodeEnum.VALID_TOKEN_ERROR));
		} else {
			// 返回 token 无效或为空
			returnJson(response, ResponseUtil.error(ResponseCodeEnum.NO_TOKEN_ERROR));
		}
		
		logger.debug("[校验授权] 未通过检验！");
		
		return false;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}
	
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}
	
	private void returnJson(HttpServletResponse response, ResponseData<?> json) throws Exception{
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(jackJsonMapper.writeValueAsString(json));
 
        } catch (IOException e) {
        	logger.error(e.getMessage());
        } finally {
            if (writer != null)
                writer.close();
        }
	}
}
